package lumis.portal.user.serialization;

import java.util.EnumSet;

import lumis.portal.PortalException;
import lumis.portal.PortalRequestParameters;
import lumis.portal.channel.ChannelConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.manager.ManagerFactoryInternal;
import lumis.portal.page.PageConfig;
import lumis.portal.serialization.BaseSerializationContext;
import lumis.portal.serialization.DeserializationContext;
import lumis.portal.serialization.SerializationContext;
import lumis.portal.serialization.SerializationMessageConfigNode;
import lumis.portal.serialization.SerializationMessageConfigNode.RecursionStopPoints;
import lumis.portal.user.UserConfig;

/**
 * Manager for User serialization
 *
 * @version $Revision: 12710 $ $Date: 2011-03-18 17:00:16 -0300 (Fri, 18 Mar 2011) $
 * @since 4.0.7
 */
public class UserSerializationManager implements IUserSerializationManager
{
	private final String[] primaryKeyFieldNames = new String[] {"id"};
	private final String[] foreignKeyFieldNames = new String[] {"channelId"};

	private final String configAlias = "user";

	// DESERIALIZATION
	
	public void deserialize(DeserializationContext deserializationContext, UserSerializableConfig userSerializableConfig) throws PortalException
	{
		deserializationContext.logDebug("Deserializing user '" + userSerializableConfig.getId() + "'");

		// deserialize config
		UserConfig userConfig = ManagerFactoryInternal.getSerializationManager2().deserializeObject(UserConfig.class, deserializationContext.getDirectory(), getConfigPath(deserializationContext, userSerializableConfig.getId()), configAlias, false);
		
		// apply id mappings
		deserializationContext.applyPrimaryKeyFieldIdMappings(userConfig, primaryKeyFieldNames);
		deserializationContext.applyForeignKeyFieldIdMappings(userConfig, foreignKeyFieldNames);
		
		// add or update config
		if (deserializationContext.isUpdateIfElementExists())
		{
			deserializationContext.logDebug(" Adding/updating user config:", userConfig);
			ManagerFactory.getUserManager().addOrUpdate(deserializationContext.getSessionConfig(), userConfig, deserializationContext.getTransaction());
		}
		else
		{
			deserializationContext.logDebug(" Adding user config:", userConfig);
			ManagerFactory.getUserManager().add(deserializationContext.getSessionConfig(), userConfig, deserializationContext.getTransaction());
		}
		
		// persist dependent configs
		deserializationContext.persistDependentConfigs(userSerializableConfig.getId());
	}
	
	// SERIALIZATION
	
	public UserSerializableConfig serialize(SerializationContext serializationContext, UserConfig userConfig) throws PortalException
	{
		// serialize config 
		ManagerFactoryInternal.getSerializationManager2().serializeObject(userConfig, serializationContext.getDirectory(), getConfigPath(serializationContext, userConfig.getId()), configAlias);
		
		// build structure object
		UserSerializableConfig userSerializableConfig = getSerializableConfig(userConfig);
		
		return userSerializableConfig;
	}

	private UserSerializableConfig getSerializableConfig(UserConfig userConfig)
	{
		UserSerializableConfig userSerializableConfig = new UserSerializableConfig();
		userSerializableConfig.setId(userConfig.getId());
		userSerializableConfig.setName(userConfig.getLogin());
		return userSerializableConfig;
	}

	public SerializationMessageConfigNode getSerializationMessageConfigNode(BaseSerializationContext baseSerializationContext, UserConfig userConfig) throws PortalException
	{
		return getSerializationMessageConfigNode(baseSerializationContext, userConfig, EnumSet.of(RecursionStopPoints.None));
	}

	public SerializationMessageConfigNode getSerializationMessageConfigNode(BaseSerializationContext baseSerializationContext, UserConfig userConfig, EnumSet<RecursionStopPoints> recursionStopPoints) throws PortalException
	{
		UserSerializationMessageConfig userSerializationMessageConfig = new UserSerializationMessageConfig();
		userSerializationMessageConfig.setId(userConfig.getId());
		userSerializationMessageConfig.setLogin(userConfig.getLogin());
		userSerializationMessageConfig.setGlobal(userConfig.getChannelId() == null);

		SerializationMessageConfigNode serializationMessageConfigNode = new SerializationMessageConfigNode();
		serializationMessageConfigNode.setSerializationMessageConfig(userSerializationMessageConfig);
		if (userConfig.getChannelId() != null) // local user
		{
			if (!recursionStopPoints.contains(RecursionStopPoints.Channel))
			{
				ChannelConfig channelConfig = ManagerFactory.getChannelManager().get(baseSerializationContext.getSessionConfig(), userConfig.getChannelId(), baseSerializationContext.getTransaction());
				serializationMessageConfigNode.getParentNodes().add(ManagerFactoryInternal.getChannelSerializationManager().getSerializationMessageConfigNode(baseSerializationContext, channelConfig));
			}
			serializationMessageConfigNode.setNavigateScript("window.parent.opener.document.location.href='../../../../"+PageConfig.PAGE_MAIN+"?"+PortalRequestParameters.PAGE_PARAMETER_CHANNELID+"="+userConfig.getChannelId()+"&"+PortalRequestParameters.PAGE_PARAMETER_PAGEID+"="+PageConfig.PAGE_ID_ADMIN_LOCALUSERS+"';return false;");
		}
		else
		{
			serializationMessageConfigNode.setNavigateScript("window.parent.opener.document.location.href='../../../../hyperlink.jsp?" + PortalRequestParameters.PAGE_PARAMETER_INTERFACE + "=lumis.service.portalmanagement.user.administration';return false;");
		}
		return serializationMessageConfigNode;
	}

	// GENERAL
	
	public void setupSerializationContext(BaseSerializationContext serializationContext)
	{
		// define serialization aliases
		serializationContext.getSerializationSettings().getClassAliases().put(UserSerializableConfig.class, "user");
	}

	/**
	 * Get the full path for the serialization file.
	 * @param deserializationContext
	 * @param configId
	 * @return
	 */
	private String getConfigPath(BaseSerializationContext deserializationContext, String configId)
	{
		return "users/" + configId + ".xml";
	}

}
